using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;

namespace Zephyris_Space_Mercs
{
    class LANMultiPlayerMenu
    {
        public static string processString = "Press Join Game to start a multiplayer game." + System.Environment.NewLine;
        bool hasSession = false;
        bool isTestingMode = false;
        PeerNode peerNode;

        int timeCounter = 0;

        List<ClickableRegion> clickableRegions = new List<ClickableRegion>();

        UI interfaceUI;
        SpriteFont uiFont;
        Texture2D uiBackground;
        Texture2D uiButton;

        GraphicsDevice device;

        public void Init(SpriteBatch spriteBatch, SpriteBatch uiBatch, GraphicsDevice device)
        {
            interfaceUI = new UI(spriteBatch, uiBatch);
            this.device = device;
        }

        public void LoadContent(Texture2D uiBackground, Texture2D uiButton, SpriteFont uiFont)
        {
            this.uiBackground = uiBackground;
            this.uiButton = uiButton;
            this.uiFont = uiFont;
        }

        public void DrawScreen()
        {
            timeCounter++;
            if (timeCounter > Constants.timeCounterVal)
                timeCounter = 0;

            interfaceUI.drawScreen(uiBackground);
            clickableRegions.Clear();

            Vector2 topleft = new Vector2(0, 0);
            Vector2 bottomright = new Vector2(0, 0);

            topleft = new Vector2((device.Viewport.Width / 2) - (uiButton.Width / 2), (device.Viewport.Height / 2) + 100);
            bottomright = new Vector2(topleft.X + this.uiButton.Width, topleft.Y + this.uiButton.Height);
            interfaceUI.drawButton(uiButton, topleft, uiFont, "Join/Start");
            AddClickable(topleft, bottomright);

            topleft = new Vector2((device.Viewport.Width / 2) - (uiButton.Width / 2), (device.Viewport.Height / 2) + 180);
            bottomright = new Vector2(topleft.X + this.uiButton.Width, topleft.Y + this.uiButton.Height);
            interfaceUI.drawButton(uiButton, topleft, uiFont, "Test");
            AddClickable(topleft, bottomright);

            Vector2 textOffset = new Vector2(0, 0);

            textOffset = new Vector2(20, 20);
            interfaceUI.drawText(textOffset, uiFont, processString);
            //AddClickable(textOffset, new Vector2(device.Viewport.Width, textOffset.Y + 40));
        }

        public void AddClickable(Vector2 topleftCorner, Vector2 bottomrightCorner)
        {
            ClickableRegion clickableRegion = new ClickableRegion();
            clickableRegion.TopLeftCorner = topleftCorner;
            clickableRegion.BottomRightCorner = bottomrightCorner;
            clickableRegions.Add(clickableRegion);
        }

        public UIPages.UIPage CheckClick(Vector2 clickedRegion)
        {
            if (timeCounter > Constants.timeCounterVal / 2)
            {
                for (int i = 0; i < clickableRegions.Count; i++)
                {
                    switch (i)
                    {
                        case 0:
                            if ((clickedRegion.X > clickableRegions[0].TopLeftCorner.X) && (clickedRegion.X < clickableRegions[0].BottomRightCorner.X)
                                &&
                                (clickedRegion.Y > clickableRegions[0].TopLeftCorner.Y) && (clickedRegion.Y < clickableRegions[0].BottomRightCorner.Y))
                            {
                                timeCounter = 0;
                                isTestingMode = false;
                                Thread THRD_Connect = new Thread(SetupMobileNetwork);
                                THRD_Connect.Start();
                                //return UIPages.UIPage.MainMenu
                            }
                            break;

                        case 1:
                            if ((clickedRegion.X > clickableRegions[1].TopLeftCorner.X) && (clickedRegion.X < clickableRegions[1].BottomRightCorner.X)
                                &&
                                (clickedRegion.Y > clickableRegions[1].TopLeftCorner.Y) && (clickedRegion.Y < clickableRegions[1].BottomRightCorner.Y))
                            {
                                timeCounter = 0;
                                isTestingMode = true;
                                Thread THRD_Connect = new Thread(SetupMobileNetwork);
                                THRD_Connect.Start();
                                //return UIPages.UIPage.MainMenu
                            }
                            break;
                    }
                }
            }

            if (hasSession)
            {
                Game1.PeerNode = this.peerNode;
                return UIPages.UIPage.LANMultiPlayer2Menu;
            }
            else
            {
                return UIPages.UIPage.LANMultiPlayerMenu;
            }
        }

        private void SetupMobileNetwork()
        {
            peerNode = new PeerNode();
            bool netError = false;

            try
            {

                if (!peerNode.RunNetwork)
                {
                    netError = !peerNode.Init();
                }

                processString = "";
                Thread.Sleep(500);   

                if (!netError && peerNode.RunNetwork)
                {
                    ConnectToSession(peerNode);

                    if (peerNode.sessionID == 0)
                    {

                        ConnectToSession(peerNode);

                        if (peerNode.sessionID == 0)
                        {

                            ConnectToSession(peerNode);

                        }
                    }

                    if (peerNode.sessionID == 0)
                    {
                        peerNode.sessionID = peerNode.networkHelpers.GetUnixEpochTime().Ticks;
                        processString += "Starting new session..." + peerNode.sessionID.ToString() + System.Environment.NewLine;
                        peerNode.IsHost = true;
                    }

                    if (peerNode.sessionID > 0)
                    {
                        if (!isTestingMode)
                        {
                            hasSession = true;
                        }
                        else
                        {
                            Ping.StartPingTest(peerNode);
                        }
                    }
                }
                else
                {
                    throw new Exception("Network Manager general failure");
                }
            }
            catch (Exception ex)
            {
                peerNode.RunNetwork = false;

                Helpers.ShowError("Network Error.", ex.Message);
            }
        }

        private void ConnectToSession(PeerNode peerNode)
        {
            bool netError;
            processString += "Searching for in progress sessions..." + System.Environment.NewLine;
            Thread.Sleep(100);
            netError = !peerNode.Send("INIT:");
            if (netError) throw new Exception("Network Manager message failure");
            Thread.Sleep(5000);
            if (peerNode.sessionID > 0)
            {
                peerNode.IsHost = false;
                processString += "Connecting to session: " + peerNode.sessionID.ToString() + System.Environment.NewLine;

                netError = !peerNode.Send("CONN");
                if (netError) throw new Exception("Cannot connect to the super node.");
            }

        }
    }
}
